#include "ModuleParsar.h"
#include "tinyxml.h"

const char *SCENEROOT	= "Scenes";
const char *SYSSCENE	= "Scene";
const char *LIBROOT		= "Libraries";
const char *LIBRARAY	= "Library";
const char *MODULE		= "Module";
const char *MODULEHOOK	= "Hook";
const char *NAME		= "Name";
const char *TYPE		= "Type";

ModuleParsar::ModuleParsar()
{
}

ModuleParsar::~ModuleParsar(void)
{
}

void ModuleParsar::Parse(const char *lpzConfig)
{
	TiXmlDocument m_xmlDocument;
	m_xmlDocument.LoadFile(lpzConfig);
	TiXmlElement *elemRoot = m_xmlDocument.RootElement();

	std::map<std::string, std::string> mapModule2Dll;
	TiXmlElement *elemLibrares = elemRoot->FirstChildElement(LIBROOT);
	TiXmlElement *elemLibrary = elemLibrares->FirstChildElement(LIBRARAY);
	while (elemLibrary)
	{
		const char *lpzDllName = elemLibrary->Attribute(NAME);
		TiXmlElement *elemModule = elemLibrary->FirstChildElement(MODULE);
		while (elemModule)
		{
			const char *lpzModuleName = elemModule->Attribute(TYPE);
			mapModule2Dll[lpzModuleName] = lpzDllName;
			elemModule = elemModule->NextSiblingElement(MODULE);
		}
		elemLibrary = elemLibrary->NextSiblingElement(LIBRARAY);
	}

	TiXmlElement *elemScenes = elemRoot->FirstChildElement(SCENEROOT);
	TiXmlElement *elemScene = elemScenes->FirstChildElement(SYSSCENE);
	while (elemScene)
	{
		const char *lpzSceneName = elemScene->Attribute(NAME);
		SceneModules sm;
		TiXmlElement *elemModule = elemScene->FirstChildElement(MODULE);
		while (elemModule)
		{
			const char *lpzModuleName = elemModule->Attribute(NAME);
			const char *lpzModuleType = elemModule->Attribute(TYPE);
			sm.m_mapModules[lpzModuleName] = lpzModuleType;
			std::map<std::string, std::string>::iterator it = mapModule2Dll.find(lpzModuleType);
			if (it != mapModule2Dll.end())
			{
				sm.m_lstLibrary.push_back(it->second);
			}
			elemModule = elemModule->NextSiblingElement(MODULE);
		}
		TiXmlElement *elemHookModule = elemScene->FirstChildElement(MODULEHOOK);
		while (elemHookModule)
		{
			const char *lpzModuleName = elemHookModule->Attribute(NAME);
			const char *lpzModuleType = elemHookModule->Attribute(TYPE);
			sm.m_mapHooks[lpzModuleName] = lpzModuleType;
			std::map<std::string, std::string>::iterator it = mapModule2Dll.find(lpzModuleType);
			if (it != mapModule2Dll.end())
			{
				sm.m_lstLibrary.push_back(it->second);
			}
			elemHookModule = elemHookModule->NextSiblingElement(MODULE);
		}
		m_mapScenes[lpzSceneName] = sm;
		elemScene = elemScene->NextSiblingElement(SYSSCENE);
	}
}

bool ModuleParsar::GetLibrary(const char *lpzScene, std::list<std::string> &lstDll)
{
	std::map<std::string, SceneModules>::iterator it = m_mapScenes.find(lpzScene);
	if (it != m_mapScenes.end())
	{
		lstDll = it->second.m_lstLibrary;
		return true;
	}
	return false;
}
bool ModuleParsar::GetModule(const char *lpzScene, std::map<std::string, std::string> &mapModules)
{
	std::map<std::string, SceneModules>::iterator it = m_mapScenes.find(lpzScene);
	if (it != m_mapScenes.end())
	{
		mapModules = it->second.m_mapModules;
		return true;
	}
	return false;
}
bool ModuleParsar::GetHooks(const char *lpzScene, std::map<std::string, std::string> &mapModules)
{
	std::map<std::string, SceneModules>::iterator it = m_mapScenes.find(lpzScene);
	if (it != m_mapScenes.end())
	{
		mapModules = it->second.m_mapHooks;
		return true;
	}
	return false;
}